package com.herr.springboot.self.xxx.common.extend;

import com.herr.springboot.self.xxx.common.anno.NoLogin;
import com.herr.springboot.self.xxx.common.constant.APIConstant;
import com.herr.springboot.self.xxx.common.enums.ApiResultEnum;
import com.herr.springboot.self.xxx.common.util.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * 请求头鉴权拦截
 * @author herr05
 */
@Component
@Slf4j
public class HeaderInterceptor implements HandlerInterceptor {

    private static final String AUTH_FAIL = "{\"code\":"+ ApiResultEnum.AUTH_FAIL.getCode()+",\"msg\":\""+ ApiResultEnum.AUTH_FAIL.getMsg()+ "\",\"data\":null}";
    private static final String TIME_OUT = "{\"code\":"+ ApiResultEnum.TIMED_OUT.getCode()+",\"msg\":\""+ ApiResultEnum.TIMED_OUT.getMsg()+ "\",\"data\":null}";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod){
            // 可直接排除特定路径
            String method=((HandlerMethod) handler).getMethod().getName();

            // 针对有noLogin注解的方法放行
            NoLogin noLoginAnnotation=((HandlerMethod) handler).getMethodAnnotation(NoLogin.class);
            if (noLoginAnnotation !=null){
                return true;
            }
            String token =request.getHeader("token");
            if (StringUtils.isNotEmpty(token)) {
                Claims claims = JwtUtils.verifyJwt(token);
                if (claims==null){
                    response.setHeader("content-type", MediaType.APPLICATION_JSON_UTF8_VALUE);
                    response.getWriter().write(AUTH_FAIL);
                    return false;
                }

                //鉴权过期校验
                Date expDate=claims.getExpiration();
                if (expDate.before(new Date())){
                    response.setHeader("content-type", MediaType.APPLICATION_JSON_UTF8_VALUE);
                    response.getWriter().write(TIME_OUT);
                    log.info(TIME_OUT);
                    return false;
                }
                //设置用户鉴权信息到request里，后续在PrincipalResolver中做参数统一解析，传回Controller
                request.setAttribute(APIConstant.API_UID, claims.get(APIConstant.API_UID,String.class));
                request.setAttribute(APIConstant.API_USERCODE, claims.get(APIConstant.API_USERCODE,String.class));
            }else {
                response.setHeader("content-type", MediaType.APPLICATION_JSON_UTF8_VALUE);
                response.getWriter().write(AUTH_FAIL);
                return false;
            }
        }
        return true;
    }
}
